package slw.core
{
	import flash.display.DisplayObject;
	import flash.display.InteractiveObject;
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.getDefinitionByName;
	
	import slw.events.LoaderEvent;
	
	/**
	 * UIComponent
	 * 轻量级控件组件基类,支持影片皮肤,无焦点管理
	 * @author ddx<br/>
	 * 2011-6-3
	 *
	 */
	public class UIComponent extends UISprite
	{
		//主容器
		private var _container:Sprite;
		//皮肤容器
		private var _skinContainer:Sprite;
		//构建组件容器
		private var _buildContainer:Sprite;
		//遮罩
		private var _maskCanvas:Shape;
		
		//可用
		private var _enabled:Boolean=true;
		
		//宽度
		private var _width:Number=0;
		//高度
		private var _height:Number=0;
		//圆角大小
		private var _round:Number=0;
		//高宽自动适应皮肤
		private var _autoSizeBySkin:Boolean=false;
		
		//皮肤数组
		private var _skin:Array=[];
		//外部皮肤地址数组
		private var _diplayURLs:Array=[];
		//外部皮肤数组
		private var _resources:Array=[];
		
		/**
		 * 构造函数
		 * 
		 */
		public function UIComponent()
		{
			super();
			
			this.listName="UIComponent";
			
			init();
		}
		
		/*
		-----------------------------------
		setter getter
		-----------------------------------
		*/
		//
		/**
		 * 组件是否激活,默认值 true(激活)
		 * @param value:Boolean
		 * 
		 */		
		public function set enabled(value:Boolean):void{
			if(_enabled==value){
				return;
			}
			_enabled=value;
			
			this.mouseEnabled=_enabled;
			if(_enabled){
				_container.alpha=1;
			}else{
				_container.alpha=.6;
			}
		}
		//
		/**
		 * 组件是否激活,默认值 true(激活)
		 * @param value:Boolean
		 * 
		 */	
		public function get enabled():Boolean{
			return _enabled;
		}
		//
		/**
		 * 高宽自动适应皮肤 
		 * @param value:Boolean 默认值:false
		 * 
		 */			
		public function set autoSizeBySkin(value:Boolean):void{
			if(_autoSizeBySkin==value){
				return;
			}
			_autoSizeBySkin=value;
			
			if(this.skin==null||this.skin.length==0){
				return;
			}
			var $temp:Array=_skin;
			this.skin=[];
			this.skin=$temp;
		}
		//
		/**
		 * 高宽自动适应皮肤 
		 * @param value:Boolean 默认值:false
		 * 
		 */	
		public function get autoSizeBySkin():Boolean{
			return _autoSizeBySkin;
		}
		//
		/**
		 * 组件皮肤数组,数组元素为可视对象的类字符串(如:["Skin1","Skin2"]),皮肤将以其在数组中的顺序进行堆放,索引0处的皮肤位于最底层,
		 * 将skin设置为[]或null清除皮肤
		 * @param value:Array
		 * 
		 */		
		public function set skin(value:Array):void{
			if(_skin==value){
				return;
			}
			_skin=value;
			
			addSkinContainer();
			
			while(_skinContainer!=null&&_skinContainer.numChildren>0){
				_skinContainer.removeChildAt(0);
				_skinContainer.scaleX=1;
				_skinContainer.scaleY=1;
			}
			
			for(var i:String in _skin){
				var $c:Class=getDefinitionByName(_skin[i]) as Class;
				var $instance:DisplayObject=new $c();
				
				if($instance is MovieClip)
					MovieClip($instance).stop();
				
				_skinContainer.addChild($instance);
			}
			if(_autoSizeBySkin){
				this.width=getMax("width");
				this.height=getMax("height");
			}else{
				this.width=this.width;
				this.height=this.height;
			}
		}
		//
		/**
		 * 组件皮肤数组,数组元素为可视对象的类字符串(如:["Skin1","Skin2"]),皮肤将以其在数组中的顺序进行堆放,索引0处的皮肤位于最底层,
		 * 将skin设置为[]或null清除皮肤
		 * @param value:Array
		 * 
		 */	
		public function get skin():Array{
			return _skin;
		}
		//
		/**
		 * 外部皮肤url数组，加载成功时，资源根显示对象被添加到皮肤容器 
		 * @param value:Array
		 * 
		 */		
		public function set displayURLs(value:Array):void{
			if(_diplayURLs==value)return;
			
			while(_resources.length>0&&_skinContainer!=null){
				_skinContainer.removeChild(_resources.pop());
			}
			_diplayURLs=value;
			addSkinContainer();
			
			loadResources(_diplayURLs);
		}
		//
		/**
		 * 外部皮肤url数组，加载成功时，资源根显示对象被添加到皮肤容器 
		 * @param value:Array
		 * 
		 */
		public function get displayURLs():Array{
			return _diplayURLs;
		}
		//
		/**
		 * 组件是否为舞台焦点 
		 * @param value:Boolean
		 * 
		 */				
		public function set focused(value:Boolean):void{
			
		}
		//
		/**
		 * 组件是否为舞台焦点 
		 * @param value:Boolean
		 * 
		 */	
		public function get focused():Boolean{
			return this.stage==null?false:this.stage.focus==this;
		}
		//
		/**
		 * 圆角大小,默认值:0px 
		 * @param value:Number
		 * 
		 */		
		public function set round(value:Number):void{
			if(_round==value)return;
			
			_round=value;
			
			updateDisplayList();
		}
		//
		/**
		 * 圆角大小,默认值:0px 
		 * @param value:Number
		 * 
		 */		
		public function get round():Number{
			return _round;
		}
		//
		/**
		 * 组件宽度，默认值 0
		 * @param value:Number
		 * 
		 */		
		override public function set width(value:Number):void{
			if(_width==value){
				return;
			}
			_width=value;
			
			if(!_autoSizeBySkin&&_skinContainer!=null)
			for(var i:int=0;i<_skinContainer.numChildren;i++){
				_skinContainer.getChildAt(i).width=_width;
			}
			
			updateDisplayList();
		}
		//
		/**
		 * 组件宽度，默认值 0 
		 * @param value:Number
		 * 
		 */
		override public function get width():Number{
			return _width;
		}
		//
		/**
		 * 组件高度，默认值 0 
		 * @param value:Number
		 * 
		 */		
		override public function set height(value:Number):void{
			if(_height==value){
				return;
			}
			_height=value;
			
			if(!_autoSizeBySkin&&_skinContainer!=null)
			for(var i:int=0;i<_skinContainer.numChildren;i++){
				_skinContainer.getChildAt(i).height=_height;
			}
			
			updateDisplayList();
		}
		//
		/**
		 * 组件高度，默认值0
		 * @param value:Number
		 * 
		 */	
		override public function get height():Number{
			return _height;
		}
		//
		/**
		 *  skin属性皮肤数组对应的实例数组
		 * @return 
		 * 
		 */		
		public function get skinTargets():Array{
			var $result:Array=[];
			if(_skinContainer!=null)
			for(var i:int=0;i<_skinContainer.numChildren;i++){
				$result.push(_skinContainer.getChildAt(i));
			}
			
			return $result;
		}
		/*
		-----------------------------------
		public  method
		-----------------------------------
		*/
		//
		/**
		 * 销毁对象实例，并释放资源(从显示列表删除，删除所有侦听)
		 * 
		 */		
		public function destroy():void{
			if(this.parent!=null){
				this.parent.removeChild(this);
			}
		}
		//
		/**
		 * 将组件移至x,y处 
		 * @param x:Number
		 * @param y:Number
		 * 
		 */		
		public function move(x:Number,y:Number):void{
			this.x=x;
			this.y=y;
		}
		//
		/**
		 * 设置组件高宽 
		 * @param width:Number
		 * @param height:Number
		 * 
		 */		
		public function setSize(width:Number,height:Number):void{
			this.width=width;
			this.height=height;
		}
		/*
		-----------------------------------
		protected  setter getter
		-----------------------------------
		*/
		//
		/**
		 * 组件主容器，是buildContainer和skinContainer的父容器 
		 * @return 
		 * 
		 */		
		public function get container():Sprite{
			return _container;
		}
		//
		/**
		 * 构建组件的内部容器 
		 * @return 
		 * 
		 */		
		public function get buildContainer():Sprite{
			return _buildContainer;
		}
		//
		/**
		 * 组件的皮肤容器 
		 * @return 
		 * 
		 */		
		public function get skinContainer():Sprite{
			return _skinContainer;
		}
		/*
		-----------------------------------
		private  method
		-----------------------------------
		*/
		//初始化
		private function init():void{
			this.mouseChildren=false;
			
			_container=new Sprite();
			this.addChild(_container);
			
			_buildContainer=new Sprite();
			_container.addChild(_buildContainer);
			
			_maskCanvas=new Shape();
			//_container.addChild(_maskCanvas);
			//_container.mask=_maskCanvas;
			
			updateDisplayList();
		}
		//更新内部显示列表
		private function updateDisplayList():void{
			drawRect(_maskCanvas,1,0,.3,0,0,_width+1,_height+1,_round,true);
			drawRect(_container,0,0,0,0,0,_width,_height,_round,true);
		}
		//绘制矩形
		private function drawRect(target:*,thickness:Number=0,color:uint=0,alpha:Number=1,x:Number=0,y:Number=0,width:Number=1,height:Number=1,round:Number=0,filled:Boolean=false):void{
			if((target as Sprite)==null&&(target as Shape)==null){
				throw new Error("target参数应为:Sprite或Shape实例及其子类实例.");
			}
			target.graphics.clear();
			if(width==0||height==0){
				return;
			}
			
			target.graphics.lineStyle(thickness,color,0,false,"none");
			if(filled)
				target.graphics.beginFill(color,alpha);
			target.graphics.drawRoundRect(x,y,width,height,round,round);
			target.graphics.endFill();
		}
		//返回属性最大值
		private function getMax(property:String):Number{
			var $result:Number=0;
			if(_skinContainer!=null)
			for(var i:int=0;i<_skinContainer.numChildren;i++){
				$result=Math.max($result,_skinContainer.getChildAt(i)[property]);
			}
			
			return $result;
		}
		//加载外部皮肤
		private function loadResources(urls:Array):void{
			if(urls==null||urls.length==0)return;
			
			var $loadIndex:int=0;
			
			var $context:LoaderContext=new LoaderContext();
			$context.applicationDomain=ApplicationDomain.currentDomain;
			var $loader:Loader=new Loader();
			$loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderComplete);
			$loader.load(new URLRequest(urls[$loadIndex]),$context);
			
			function loaderComplete(e:Event):void{
				_resources.push($loader.content);
				addSkinContainer();
				if(this is UIComponent)
					_skinContainer.addChild($loader.content);
				
				$loadIndex++;
				if($loadIndex<urls.length){
					$loader.load(new URLRequest(urls[$loadIndex]),$context);
				}else{
					$loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,loaderComplete);
					
					dispatch(new LoaderEvent(LoaderEvent.LOAD_COMPLETE,false,false,$loader.content,_resources));
				}
			}
		}
		//
		private function dispatch(e:LoaderEvent):void{
			this.dispatchEvent(e);
		}
		//添加删除皮肤容器
		private function addSkinContainer():void{
			if(_skinContainer==null&&((_skin!=null&&_skin.length!=0)||(_resources!=null&&_resources.length!=0))){
				_skinContainer=new Sprite();
				_container.addChildAt(_skinContainer,0);
			}else if(_skinContainer!=null&&(_skin==null&&_skin.length==0)){
				_container.removeChild(_skinContainer);
				_skinContainer=null;
			}
		}
	}
}